//1.成绩判断
function isLevel(a) {
    if (a >= 90) {
        return "优秀";
    } else if (a >= 80) {
        return "良好";
    } else if (a >= 70) {
        return "一般";
    } else if (a >= 60) {
        return "及格";
    } else {
        return "不及格";
    }
}

//2.判断闰年
function isRun(year) {
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
        return true;
    } else {
        return false;
    }
}

//3.判断素数
function isSu() {
    var flag = true;
    for (var i = 2; i < num; i++) {
        if (num % i == 0) {
            flag = false;
            break;
        }
    }
    return flag;
}

//3.年份输入是否正确
function isYearOk(year) {
    return year >= 1000 && year <= 9999 && year % 1 == 0 ? true : false;
}

//4.月份输入是否正确
function isMonthOk(month) {
    return month >= 1 && month <= 12 && month % 1 == 0 ? true : false;
}

//5. 2月的日期是否正确
function isDayOk(year, month, day) {
    var maxDay;
    switch (month * 1) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            maxDay = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            maxDay = 30;
            break;
        case 2:
            maxDay = isRun(year) ? 29 : 28;
            break;
        default:
            break;
    }
    return day >= 1 && day <= maxDay && day % 1 == 0 ? true : false;
}

//6.计算当天是一年内多少天
function getTotalDay(year, month, day) {
    var febDay = isRun(year) ? 29 : 28;
    var sum = 0;
    switch (month * 1) {
        case 12:
            sum += 31;
        case 11:
            sum += 30;
        case 10:
            sum += 31;
        case 9:
            sum += 30;
        case 8:
            sum += 31;
        case 7:
            sum += 31;
        case 6:
            sum += 30;
        case 5:
            sum += 31;
        case 4:
            sum += 30;
        case 3:
            sum += 31;
        case 2:
            sum += febDay;
        case 1:
            sum += day * 1;
            break;
        default:
            break;
    }
    return sum;
}

//7.上等腰三角形
function isTig1(n) {
    for (var i = 1; i <= n; i++) {
        for (var j = 1; j <= n - i; j++) {
            document.write("&emsp;");
        }
        for (var k = 1; k <= 2 * i - 1; k++) {
            document.write("星");
        }
        document.write("<br>");
    }
}

//8.下等腰三角形
function isTig2(n) {
    for (var i = n; i >= 1; i--) {
        for (var j = 1; j <= n - i; j++) {
            document.write("&emsp;");
        }
        for (var k = 1; k <= 2 * i - 1; k++) {
            document.write("星");
        }
        document.write("<br>");
    }
}

//9.菱形
function isDmd(n) {
    var mid = parseInt(n / 2);
    for (var i = -mid; i <= mid; i++) {
        for (var j = 1; j <= Math.abs(i); j++) {
            document.write("&emsp;");
        }
        for (var k = 1; k <= n - Math.abs(i) * 2; k++) {
            document.write("星");
        }
        document.write("<br>");
    }
}

//10.九九乘法表
function isMpt() {
    var z = 0, str = "";
    for (var i = 1; i <= 9; i++) {
        for (var j = 1; j <= i; j++) {
            z = i * j;
            str += j + " x " + i + " = " + z;
        }
        str = str + "<br>";
    }
    return str;
}

//11. 一个新入职，月工资为2000元的员工，每年涨当年工资5%，到退休20年时的月工资是多少？
function getSalaryAfter(Salary) {
    for (var i = 1; i < 20; i++) {
        Salary += Salary * 0.05;
    }
    return Salary.toFixed(2);
}

//12.山上有一口缸可以装50升水，现在有15升水。老和尚叫小和尚下山挑水，每次可以挑5升。问：小和尚要挑几次水才可以把水缸挑满？通过编程解决这个问题。
function getWater(nowWater) {
    var x = 0;
    for (var i = nowWater; i < 50; i += 5) {
        x++;
    }
    return x;
}

//13.输出100-999的水仙花数
function isDaffodil() {
    var x, y, z;
    for (var i = 100; i <= 999; i++) {
        x = parseInt(i / 100);
        y = parseInt(i / 10 % 10);
        z = parseInt(i % 10);
        if (i == x * x * x + y * y * y + z * z * z) {
            document.write(i + "<br>");
        }
    }
}

//14.最大公约数和最小公倍数（递归）
function commonDivisor(max, min) {
    var num;
    if (max < min) {
        num = max;
        max = min;
        min = num;
    }
    var x = max % min;
    if (x == 0) {
        return min;
    }
    return commonDivisor(min, x);
}

//15.斐波拉契数列（递归）
function fn(n) {
    if (n <= 2) {
        return 1;
    }
    return fn(n - 1) + fn(n - 2);
}

//16.判断数据长度
function isLength(l) {
    if (l.length >= 6 && l.length <= 12) {
        return true;
    }
    return false;
}


//17.判断是否以数字开头
function isNum(firstChar) {
    if (isNaN(firstChar)) {
        return true;
    }
    return false;
}

//18.获取数字数组
function numList() {
    var numList = [];
    for (var i = 48; i <= 57; i++) {
        var char = String.fromCharCode(i); //根据编码返回对应的字符
        numList.push(char);
    }
    return numList;
}

//19.获取大写字母数组
function maxList() {
    var maxList = [];
    for (var i = 65; i <= 90; i++) {
        var char = String.fromCharCode(i); //根据编码返回对应的字符
        maxList.push(char);
    }
    return maxList;
}

//20.获取小写字母数组
function minList() {
    var minList = [];
    for (var i = 97; i <= 122; i++) {
        var char = String.fromCharCode(i); //根据编码返回对应的字符
        minList.push(char);
    }
    return minList;
}

//21.获取特殊字符
function characters() {
    var characters = ["_", "!", "$"];
    return characters;
}

//22.获取大小写数字特殊字符
function chars() {
    var chars = numList().concat(maxList(), minList(), characters());
    return chars;
}

//23.判断字符是否合法
function isContrast(arr) {
    // console.log(chars());
    // console.log(numList());
    var falg = true;
    for (var i = 0; i < arr.length; i++) {
        if (chars().indexOf(arr[i]) == -1) { //返回某个元素在数组中第一次出现的位置(下标),不存在返回-1
            falg = false;
            break;
        }
    }
    return falg;
}

//24.递归深复制 (多维数组)
function deepCopy(list) {
    // console.log(list);
    var arr = [];
    for (var i = 0; i < list.length; i++) {
        var item = list[i];
        if (!(Array.isArray(item))) { //如果不是数组，复制到arr
            arr.push(item);
        } else {  //如果是数组，执行递归操作
            arr.push(deepCopy(item));
        }
    }
    return arr;
}

//25.判断密码是否存在
function maxExistence(arr) {
    var falg = false;
    for (var i = 0; i < arr.length; i++) {
        if (maxList().indexOf(arr[i]) != -1) { //返回某个元素在数组中第一次出现的位置(下标),不存在返回-1
            falg = true;
            break;
        }
    }
    return falg;
}
function minExistence(arr) {
    var falg = false;
    for (var i = 0; i < arr.length; i++) {
        if (minList().indexOf(arr[i]) != -1) { //返回某个元素在数组中第一次出现的位置(下标),不存在返回-1
            falg = true;
            break;
        }
    }
    return falg;
}
function numExistence(arr) {
    var falg = false;
    for (var i = 0; i < arr.length; i++) {
        if (numList().indexOf(arr[i]) != -1) { //返回某个元素在数组中第一次出现的位置(下标),不存在返回-1
            falg = true;
            break;
        }
    }
    return falg;
}
function charsExistence(arr) {
    var falg = false;
    for (var i = 0; i < arr.length; i++) {
        if (characters().indexOf(arr[i]) != -1) { //返回某个元素在数组中第一次出现的位置(下标),不存在返回-1
            falg = true;
            break;
        }
    }
    return falg;
}

//26.随机验证码
function myRandom() {
    var list = chars();
    var arr = [];
    var j;
    while (true) {
        j = Math.round(Math.random() * (list.length - 4));
        if (arr.indexOf(list[j]) == -1) {
            arr.push(list[j]);
        }
        if (arr.length == 4) break;
    }
    return arr.join("");
}

//27.传入一个日期, 返回该月的第一天 是星期几 ? (星期天)
function week(day) {
    var date = day == undefined ? new Date() : new Date(day);//获取传入的日期
    date.setDate(1); //将日期改为该月的第一天
    var week = date.getDay(); //获取该日（该月的第一天）期是周几
    week = week == 0 ? 7 : week; //如果0则+7该为7（为星期天），因为默认星期天为0
    return week; //返回星期几
}

//28.传入一个日期, 返回该日期对应的上个月有多少天 ? (上个月)
function beforeMonthDay(day) {
    var date = day == undefined ? new Date() : new Date(day);//获取传入的日期
    date.setDate(0); //将当月的号数改为0号（也就是上个月的最后一天），由此可以判断上个月有多少天
    var sum = date.getDate(); //再获取号数（几号）
    return sum;
}

//29.传入一个日期, 返回该日期对应的月有多少天 ? (当前月)
function monthDay(day) {
    var date = day == undefined ? new Date() : new Date(day);//获取传入的日期
    date.setDate(1);
    var month = date.getMonth(); //获取传入日期的月份
    date.setMonth(month + 1); //将月份+1，默认月份是0-11
    date.setDate(0); //将当月的号数改为0号（也就是上个月的最后一天），由此可以判断上个月有多少天
    var sum = date.getDate(); //再获取号数（几号）
    return sum;
}

//30.日期格式化
function dateFormat(replace, date) {
    var date = day == undefined ? new Date() : new Date(date);
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    var hour = date.getHours();
    var minute = date.getMinutes();
    var second = date.getSeconds();
    return replace.replace("YY", year).replace("MM", month).replace("DD", day).replace("hh", hour).replace("mm", minute).replace("ss", second);
}

//31.模拟封装通过class名获取元素方法
function myGetElementsByClassName(className) {
    var all = document.getElementsByTagName("*");
    var arr = [];
    for (var i = 0; i < all.length; i++) {
        var ele = all[i];  //遍历集合 => 每一个html元素
        var _class = ele.getAttribute("class");
        if (_class) { // 如果含有class名
            var classList = _class.split(" "); //用空格拆分成数组再遍历
            if (myIndexOf(classList, className) != -1) {
                arr.push(ele);
            }
        }
    }
    return arr;
}

//32.indexOf的模拟封装方法
function myIndexOf(arr, char) {
    var index = -1; //假设不存在 -1
    for (var i = 0; i < arr.length; i++) {
        var item = arr[i];
        if (item === char) {
            index = i;  //存在就记录下标
        }
    }
    return index;
}

//33.js获取非行内样式的兼容ie方法
function getStyle(ele, attr) {
    if (window.getComputedStyle) {  //取值 判断方法是否存在   存在:常规浏览器
        return window.getComputedStyle(ele)[attr];
    } else {  //不存在 => IE
        return ele.currentStyle[attr];
    }
}

//34.当前元素的前一个元素
function prev(ele) {
    return ele.previousElementSibling || ele.previousSibling;
}

//35.当前元素的后一个元素
function next(ele) {
    return ele.nextElementSibling || ele.nextSibling;
}

//36.当前元素的父元素
function parent(ele) {
    return ele.parentElement;
}

//37.Js运动 传入元素，css样式，速度，终点，计时器时间
function animate(ele, attr, speed, end, time) {
    //传统的获取非行内样式
    //cur 1. 记录盒子最开始的初始值  2. 记录每次运动时的当前位置
    var cur = parseFloat(getStyle(ele, attr));
    end = parseFloat(end);
    var speed = end > cur ? speed : -speed;
    clearInterval(timer);
    var timer = setInterval(function () {
        cur += speed;
        ele.style[attr] = cur + "px";
        if (Math.abs(end - cur) <= Math.abs(speed)) {
            clearInterval(timer);
            ele.style[attr] = end + "px";
        }
    }, time);
}

//38.随机颜色rgba
function randColoRgb() {
    return Math.round(Math.random() * 255);
}

//39.随机颜色十六进制
function randColor() {
    var str = "0123456789abcdef";
    var colorStr = "#";
    for (var i = 0; i < 6; i++) {
        var index = Math.floor(Math.random() * str.length);
        var char = str.charAt(index);
        colorStr += char;
    }
    return colorStr;
}

//40.Js链式运动 传入元素，css样式，终点
// aniType 运动方式  (normal fast slow)
// fn      回调函数,在运动结束时执行   多物体运动需在timer前面加一个ele.
function animate(ele, attr, end, aniType = "normal", fn) {
    //传统的获取非行内样式
    //cur 1. 记录盒子最开始的初始值  2. 记录每次运动时的当前位置
    var cur = parseFloat(getStyle(ele, attr));
    end = parseFloat(end);
    var speed = 0; //初始速度
    clearInterval(timer);
    var timer = setInterval(function () {
        if (aniType == "normal") {
            // 匀速运动
            speed = end > cur ? 20 : -20;
        } else if (aniType == "fast") {
            // 加速运动
            speed = end > cur ? speed + 5 : speed - 5;
        } else if (aniType == "slow") {
            // 减速运动
            speed = (end - cur) / 10;
            speed = end > cur ? Math.ceil(speed) : Math.floor(speed);
        }
        cur += speed;
        ele.style[attr] = cur + "px";
        // console.log(cur, end, speed);
        if (Math.abs(end - cur) <= Math.abs(speed)) {
            clearInterval(timer);
            ele.style[attr] = end + "px";

            if (fn) { //如果传入回调函数 => 在结束运动后执行
                fn()
            }
        }
    }, 10);
}

// 41.创建cookie
// key：键名 val：键值 day：过期时间 path：存储路径
function setCookie(key, val, day, path = "/") {
    if (day) { //如果传入过期时间
        var date = new Date();
        date.setDate(date.getDate() + day);
        document.cookie = `${key}=${val};expires=${date.toUTCString()};path=/`;
    } else {
        document.cookie = `${key}=${val};path=/`;
    }
}

// 42.获取cookie
function getCookie(key) {
    var cookie = document.cookie;
    if (cookie) {
        var list = cookie.split("; "); //将cookie通过"; "拆分成数组
        for (var i = 0; i < list.length; i++) {
            var name = list[i].split("=")[0]; //通过等号拆分，把键名给nane
            var val = list[i].split("=")[1]; //通过等号拆分，把键值给val
            if (key === name) { //如果键值和name相等，直接返回键值
                return val;
            }
        }
    }
    return "";
}

// 43.ajax封装
// 模拟封装 jquery中的ajax
// $ 对象 => 存储了三个方法
// $.ajax({
//     type,    请求方式
//     url      请求地址
//     data     传递的数据(string|object)  如果是对象 => 遍历对象转化为参数数据队列
//     async    是否异步
//     dataType 接口返回的数据类型(text(默认) / html / json)
//     success  回调函数 => 请求成功时执行的内容(回调函数有一个形式参数  用于接收接口返回的结果)
// })
var $ = {
    get: function (options) {
        var { url, data, async = true, dataType = "text", success } = options

        if (typeof data == "object") {
            var str = "";
            for (var key in data) {
                var val = data[key];
                str += key + "=" + val + "&";
            }
            data = str.substring(0, str.length - 1);
        }

        var xhr = new XMLHttpRequest();
        xhr.open("get", `${url}?${data}`, async);
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                var result = xhr.responseText;
                // 如果用户说 返回的数据是json => JSON.parse();
                if (dataType == "json") {
                    result = JSON.parse(result);
                }
                // 获取接口响应的结果之后  => 用户执行的内容并不是固定的
                if (success) {
                    success(result);// 回调函数在执行过程中 => 将请求的结果作为实际参数传入
                }
            }
        }
    },

    post: function (options) {
        var { url, data, async = true, dataType = "text", success } = options
        if (typeof data == "object") {
            var str = "";
            for (var key in data) {
                var val = data[key];
                str += key + "=" + val + "&";
            }
            data = str.substring(0, str.length - 1);
        }


        var xhr = new XMLHttpRequest();
        xhr.open("post", `${url}`, async);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.send(`${data}`);

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                var result = xhr.responseText;
                // 如果用户说 返回的数据是json => JSON.parse();
                if (dataType == "json") {
                    result = JSON.parse(result);
                }
                // 获取接口响应的结果之后  => 用户执行的内容并不是固定的
                if (success) {
                    success(result);// 回调函数在执行过程中 => 将请求的结果作为实际参数传入
                }
            }
        }
    },

    ajax: function (options) {
        var { url, data, async = true, dataType = "text", success, type = "get" } = options
        // data instanceof Object   不准确 且听下回分解
        if (typeof data == "object") {
            var str = "";
            for (var key in data) {
                var val = data[key];
                str += key + "=" + val + "&";
            }
            data = str.substring(0, str.length - 1);
        }

        var xhr = new XMLHttpRequest();
        // 如果请求方式为post
        if (type.toLowerCase() == "post") {
            xhr.open("post", `${url}`, async);
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xhr.send(`${data}`);
        } else {
            xhr.open("get", `${url}?${data}`, async);
            xhr.send();
        }

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                var result = xhr.responseText;
                // 如果用户说 返回的数据是json => JSON.parse();
                if (dataType == "json") {
                    result = JSON.parse(result);
                }
                // 获取接口响应的结果之后  => 用户执行的内容并不是固定的
                if (success) {
                    success(result);// 回调函数在执行过程中 => 将请求的结果作为实际参数传入
                }
            }
        }
    }
}